package Tracker.server.control;

import org.json.JSONException;
import org.json.JSONObject;

import Tracker.server.ClientHandler;
import Tracker.server.model.Model;
import Tracker.server.model.TError;
import Tracker.server.model.Session;

public class ProtocolHandler {
	Model model;
	ClientHandler client;
	
	Session session;
	
	public ProtocolHandler(Model m, ClientHandler h) {
		this.model = m;
		this.client = h;
	}
	
	
	public String parse(String message) {
		try {
			JSONObject req = new JSONObject(message);
//			System.out.println("Request: " + req.toString());
			
			JSONObject res = new JSONObject();
			String command = null;
			
			try { // Get Command
				command = req.get("command").toString();
			} catch (JSONException e) {
				res.append("success", new Boolean(false));
				res.append("error", new TError("No command string", 400));
				return res.toString();
			}
			
			// Login or find session
			if(command.equals("login")) {
				LoginController c = new LoginController(this);
				c.login(req, res);
			} else {
				try { // Validate Session
					JSONObject s = req.getJSONObject("session");
					try {
						this.session = this.model.getSession(s.getInt("id"));
						if(session == null) {
							res.append("success", new Boolean(false));
							res.append("error", new TError("Invalid session id", 401));
							return res.toString();
						}
						
						// Route to controller for command
						if(command.equals("logout")) {
							LoginController c = new LoginController(this);
							c.logout(req, res);
						} else if(command.equals("getSession")) {
							SessionController c = new SessionController(this);
							c.get(req, res);
						} else if(command.equals("getTracks")) { // Tracks
							TrackController c = new TrackController(this);
							c.get(req, res);
						} else if(command.equals("addTrack")) {
							TrackController c = new TrackController(this);
							c.create(req, res);
						} else if(command.equals("updateTrack")) {
							TrackController c = new TrackController(this);
							c.update(req, res);
						} else if(command.equals("userUpdate")) { // User
							UserController c = new UserController(this);
							c.update(req, res);
						} else if(command.equals("upload")) { // User
							UploadController c = new UploadController(this);
							c.upload(req, res);
						} else {
							InvalidController c = new InvalidController(this);
							c.parse(req, res);
						}
						
					} catch (Exception eee) {
						res.append("success", new Boolean(false));
						res.append("error", new TError("Invalid session object", 400));
						eee.printStackTrace();
						return res.toString();
					}
				} catch (Exception ee) {
					res.append("success", new Boolean(false));
					res.append("error", new TError("No session object", 400));
					return res.toString();
				}
			}
			return res.toString();
			
		} catch (JSONException e) { // Something bad happened. Bail! Bail! Bail!
				return "{ \"success\" : \"false\", \"error\" : {\"message\" : \"Failboat.\", \"code\" : \"500\" } }";
		}
	}
}
